//*****************************************************************//
//fake module,just for test
//*****************************************************************//
module fake_systolic_muxed (
    input  wire        clk,
    input  wire        reset,
    input  wire        start,           // 启动输出
    input  wire [1:0]  matrix_type,     // 0:`m16n16k16  1:`m8n32k16  2:`m32n8k16
    output reg  [31:0] c_out_muxed,     // 分时复用输出
    output reg         c_out_valid,     // 输出有效
    output reg         done             // 输出完成
);

    // 宏定义（可根据实际define.sv调整）
    localparam m16n16k16 = 2'd0;
    localparam m8n32k16  = 2'd1;
    localparam m32n8k16  = 2'd2;

    // 1. ROM初始化，内容为D_int32_m16n16k16_hex.txt
    reg [31:0] c_out [0:15][0:15];
    initial begin
        c_out[0][0]  = 32'h2509624f; c_out[0][1]  = 32'hb5392e56; c_out[0][2]  = 32'h84f50a75; c_out[0][3]  = 32'h92b2d1c5;
        c_out[0][4]  = 32'h2253ecde; c_out[0][5]  = 32'h7852cf36; c_out[0][6]  = 32'h4941f0de; c_out[0][7]  = 32'h7e7b4e37;
        c_out[0][8]  = 32'h4856ed3d; c_out[0][9]  = 32'h33f6da74; c_out[0][10] = 32'hc459cc12; c_out[0][11] = 32'h4d76cbb6;
        c_out[0][12] = 32'h66f375b2; c_out[0][13] = 32'hdaff31c9; c_out[0][14] = 32'h0604c816; c_out[0][15] = 32'hef40b764;
        c_out[1][0]  = 32'h94847211; c_out[1][1]  = 32'h1b835951; c_out[1][2]  = 32'h990cf24b; c_out[1][3]  = 32'hb326fd3e;
        c_out[1][4]  = 32'h8767c130; c_out[1][5]  = 32'h3b370c09; c_out[1][6]  = 32'h6b948847; c_out[1][7]  = 32'h0d0ce3b2;
        c_out[1][8]  = 32'hc3f4d8af; c_out[1][9]  = 32'h9460072a; c_out[1][10] = 32'hc67b2536; c_out[1][11] = 32'h47d83449;
        c_out[1][12] = 32'hc354d5f0; c_out[1][13] = 32'h381136b2; c_out[1][14] = 32'hf5c256b4; c_out[1][15] = 32'h8d260086;
        c_out[2][0]  = 32'hc86fd4a6; c_out[2][1]  = 32'hc1b5fa8b; c_out[2][2]  = 32'h70afad4b; c_out[2][3]  = 32'h088af034;
        c_out[2][4]  = 32'h823e885e; c_out[2][5]  = 32'h80040000; c_out[2][6]  = 32'h93782f5c; c_out[2][7]  = 32'h90f99b3f;
        c_out[2][8]  = 32'hd641b2cc; c_out[2][9]  = 32'hb2d3b076; c_out[2][10] = 32'hb9c367e7; c_out[2][11] = 32'h1a68c930;
        c_out[2][12] = 32'hcffc90da; c_out[2][13] = 32'h358dce7f; c_out[2][14] = 32'h2741df4f; c_out[2][15] = 32'h28ffd0b8;
        c_out[3][0]  = 32'h7177772f; c_out[3][1]  = 32'h9087a87e; c_out[3][2]  = 32'h49bd4e8b; c_out[3][3]  = 32'h5894175c;
        c_out[3][4]  = 32'h69bd3422; c_out[3][5]  = 32'h909efa65; c_out[3][6]  = 32'hd87b9db4; c_out[3][7]  = 32'hd4e4bbc5;
        c_out[3][8]  = 32'h429aa847; c_out[3][9]  = 32'he4760ae2; c_out[3][10] = 32'h89982aa6; c_out[3][11] = 32'haeb58e71;
        c_out[3][12] = 32'ha1bd8d17; c_out[3][13] = 32'h031bb2a2; c_out[3][14] = 32'h6e8ecaa2; c_out[3][15] = 32'h68e72709;
        c_out[4][0]  = 32'hac1160d3; c_out[4][1]  = 32'h9454331f; c_out[4][2]  = 32'h16d30bbf; c_out[4][3]  = 32'h98a83c71;
        c_out[4][4]  = 32'hec91dd4a; c_out[4][5]  = 32'h564ffed7; c_out[4][6]  = 32'hf722754f; c_out[4][7]  = 32'h3e74f74c;
        c_out[4][8]  = 32'h9f450ff4; c_out[4][9]  = 32'h9b31c925; c_out[4][10] = 32'hf1f8243b; c_out[4][11] = 32'ha1117501;
        c_out[4][12] = 32'h8d021288; c_out[4][13] = 32'h153db2dc; c_out[4][14] = 32'h7168fe34; c_out[4][15] = 32'h84b2ea90;
        c_out[5][0]  = 32'h24575b07; c_out[5][1]  = 32'hdbfea4c7; c_out[5][2]  = 32'h1b224bf0; c_out[5][3]  = 32'h032ae911;
        c_out[5][4]  = 32'hf0e53802; c_out[5][5]  = 32'h3f124211; c_out[5][6]  = 32'h262f20bd; c_out[5][7]  = 32'h7ffc0800;
        c_out[5][8]  = 32'h846a6940; c_out[5][9]  = 32'hd9d892fc; c_out[5][10] = 32'hd1c85c23; c_out[5][11] = 32'h6f41fd70;
        c_out[5][12] = 32'h1103333d; c_out[5][13] = 32'h35fca1f8; c_out[5][14] = 32'h2ad4e875; c_out[5][15] = 32'hf7f651d4;
        c_out[6][0]  = 32'h9fa9eb21; c_out[6][1]  = 32'h4f6a7e4d; c_out[6][2]  = 32'hc5d7d180; c_out[6][3]  = 32'hc3f59354;
        c_out[6][4]  = 32'h412d8290; c_out[6][5]  = 32'h7b32ba17; c_out[6][6]  = 32'hb4c2379a; c_out[6][7]  = 32'h584235e9;
        c_out[6][8]  = 32'he5d933f5; c_out[6][9]  = 32'h796ee202; c_out[6][10] = 32'h5323225c; c_out[6][11] = 32'h54708754;
        c_out[6][12] = 32'h7d464f40; c_out[6][13] = 32'hc7d0346c; c_out[6][14] = 32'h2bfeedba; c_out[6][15] = 32'h0f7e6673;
        c_out[7][0]  = 32'hb74d1ae8; c_out[7][1]  = 32'ha8e4777f; c_out[7][2]  = 32'h1de041b6; c_out[7][3]  = 32'h5179ca9f;
        c_out[7][4]  = 32'h7a8bd6d0; c_out[7][5]  = 32'h4b3fb55c; c_out[7][6]  = 32'h4991e5d5; c_out[7][7]  = 32'he9e351a8;
        c_out[7][8]  = 32'h97ba8752; c_out[7][9]  = 32'hf5b4f4f5; c_out[7][10] = 32'h56e47ffc; c_out[7][11] = 32'hc47baeb1;
        c_out[7][12] = 32'h861d21f0; c_out[7][13] = 32'h23e4d93e; c_out[7][14] = 32'hcc55fec0; c_out[7][15] = 32'h9f7b2731;
        c_out[8][0]  = 32'h7610df0b; c_out[8][1]  = 32'ha2a6b3b7; c_out[8][2]  = 32'h0c4f69d7; c_out[8][3]  = 32'h775ae1c8;
        c_out[8][4]  = 32'h1a7c5d59; c_out[8][5]  = 32'he9c3ad3c; c_out[8][6]  = 32'h28fc9836; c_out[8][7]  = 32'habfd7c49;
        c_out[8][8]  = 32'h09115ec4; c_out[8][9]  = 32'h8c5c3043; c_out[8][10] = 32'h821e6ef7; c_out[8][11] = 32'h5ba7c321;
        c_out[8][12] = 32'h5a1e21e4; c_out[8][13] = 32'h5032d8ee; c_out[8][14] = 32'h1309ae1c; c_out[8][15] = 32'h820eb8e6;
        c_out[9][0]  = 32'h6f0b5215; c_out[9][1]  = 32'hd6f8f83c; c_out[9][2]  = 32'heb41b4e8; c_out[9][3]  = 32'h1b019f65;
        c_out[9][4]  = 32'h6806bcf1; c_out[9][5]  = 32'he1be9889; c_out[9][6]  = 32'he5b533f0; c_out[9][7]  = 32'hc8f05a62;
        c_out[9][8]  = 32'h9b0d35fa; c_out[9][9]  = 32'h38cc496e; c_out[9][10] = 32'h232d8c04; c_out[9][11] = 32'h12aad077;
        c_out[9][12] = 32'h6286b42f; c_out[9][13] = 32'h94ae4978; c_out[9][14] = 32'h476381b3; c_out[9][15] = 32'h71b75db0;
        c_out[10][0] = 32'h62b636f5; c_out[10][1] = 32'h8c76733c; c_out[10][2] = 32'h3ccc9ca1; c_out[10][3] = 32'h5a203646;
        c_out[10][4] = 32'hae814416; c_out[10][5] = 32'h91af6e01; c_out[10][6] = 32'h9aa57335; c_out[10][7] = 32'h0c60c3b5;
        c_out[10][8] = 32'h1ba7a647; c_out[10][9] = 32'h2d245538; c_out[10][10]= 32'h25d95f01; c_out[10][11]= 32'hf22800c7;
        c_out[10][12]= 32'hbfa70e2b; c_out[10][13]= 32'h89c5248f; c_out[10][14]= 32'h5b617c98; c_out[10][15]= 32'h9d1d5037;
        c_out[11][0] = 32'h7ddb3c3f; c_out[11][1] = 32'h0d1c805a; c_out[11][2] = 32'hafc1d0ce; c_out[11][3] = 32'hd6cee8e1;
        c_out[11][4] = 32'hf679f6db; c_out[11][5] = 32'h2d1a058c; c_out[11][6] = 32'h70aec881; c_out[11][7] = 32'h9691c1fa;
        c_out[11][8] = 32'hf7fdb98e; c_out[11][9] = 32'hcd6f4603; c_out[11][10]= 32'h5bbe25eb; c_out[11][11]= 32'ha7695c87;
        c_out[11][12]= 32'h18865496; c_out[11][13]= 32'hc62fc572; c_out[11][14]= 32'h3511c7da; c_out[11][15]= 32'hbf748498;
        c_out[12][0] = 32'h46964e8f; c_out[12][1] = 32'h109ef175; c_out[12][2] = 32'h10423cb0; c_out[12][3] = 32'hc82077de;
        c_out[12][4] = 32'hfe836c0a; c_out[12][5] = 32'hcae72ea7; c_out[12][6] = 32'h0e64b45c; c_out[12][7] = 32'h16b16403;
        c_out[12][8] = 32'h74f2b120; c_out[12][9] = 32'h34fc09d2; c_out[12][10]= 32'h82fef632; c_out[12][11]= 32'h8312c0ae;
        c_out[12][12]= 32'he16d207d; c_out[12][13]= 32'h845f1496; c_out[12][14]= 32'h1174cb69; c_out[12][15]= 32'h12231348;
        c_out[13][0] = 32'h7ccae3ac; c_out[13][1] = 32'h81f51de9; c_out[13][2] = 32'hb9b34088; c_out[13][3] = 32'h4e022797;
        c_out[13][4] = 32'hc2c13854; c_out[13][5] = 32'hb2ff9633; c_out[13][6] = 32'h761c3850; c_out[13][7] = 32'h5e879402;
        c_out[13][8] = 32'h8e66c61e; c_out[13][9] = 32'h142a5836; c_out[13][10]= 32'h8db71196; c_out[13][11]= 32'h3e88e5c1;
        c_out[13][12]= 32'h200c1d5b; c_out[13][13]= 32'hfd856e7b; c_out[13][14]= 32'h73992fe1; c_out[13][15]= 32'h44c3e2d4;
        c_out[14][0] = 32'h253a961c; c_out[14][1] = 32'ha8c84260; c_out[14][2] = 32'hc74e277b; c_out[14][3] = 32'h7486ee41;
        c_out[14][4] = 32'h9267df79; c_out[14][5] = 32'h45fed2df; c_out[14][6] = 32'h28808ba1; c_out[14][7] = 32'h331a1de0;
        c_out[14][8] = 32'h48a195de; c_out[14][9] = 32'ha83865e3; c_out[14][10]= 32'h1fb6ca6d; c_out[14][11]= 32'he062aa91;
        c_out[14][12]= 32'h7a792760; c_out[14][13]= 32'h78d08ee3; c_out[14][14]= 32'ha957115a; c_out[14][15]= 32'h4106280c;
        c_out[15][0] = 32'h6106b8af; c_out[15][1] = 32'h4cb1b7b8; c_out[15][2] = 32'h9758396d; c_out[15][3] = 32'h9d7bf4de;
        c_out[15][4] = 32'h85f5fb7c; c_out[15][5] = 32'h83a50917; c_out[15][6] = 32'h21355a0f; c_out[15][7] = 32'he00198d9;
        c_out[15][8] = 32'heb750aca; c_out[15][9] = 32'hd8b7b056; c_out[15][10]= 32'h731cb4c5; c_out[15][11]= 32'hd0eb8068;
        c_out[15][12]= 32'ha43c88df; c_out[15][13]= 32'hc9ca1c0d; c_out[15][14]= 32'h1b8741da; c_out[15][15]= 32'he33e8a69;
    end

    // 2. 分时复用输出逻辑
    reg [7:0] counter;
    reg output_en;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            counter      <= 8'd0;
            output_en    <= 1'b0;
            c_out_muxed  <= 32'd0;
            c_out_valid  <= 1'b0;
            done         <= 1'b0;
        end else begin
            if (start && !output_en) begin
                output_en   <= 1'b1;
                counter     <= 8'd0;
                done        <= 1'b0;
            end else if (output_en) begin
                // 分时复用逻辑
                case (matrix_type)
                    m16n16k16: begin
                        c_out_muxed <= c_out[counter[7:4]][counter[3:0]];
                    end
                    m8n32k16: begin
                        if (counter[4:0] < 5'd16)
                            c_out_muxed <= c_out[counter[7:5]][counter[4:0]];
                        else
                            c_out_muxed <= c_out[counter[7:5] + 5'd8][counter[4:0] - 5'd16];
                    end
                    m32n8k16: begin
                        if (counter[7:3] < 5'd16)
                            c_out_muxed <= c_out[counter[7:3]][counter[2:0]];
                        else
                            c_out_muxed <= c_out[counter[7:3] - 5'd16][counter[2:0] + 4'd8];
                    end
                    default: begin
                        c_out_muxed <= 32'd0;
                    end
                endcase
                c_out_valid <= 1'b1;
                if (counter == 8'd255) begin
                    output_en   <= 1'b0;
                    done        <= 1'b1;
                end else begin
                    counter <= counter + 1'b1;
                end
            end else begin
                c_out_valid <= 1'b0;
            end
        end
    end

endmodule 